home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Tcl-Tk 8.0 / Pre-installed version / tk8.0 / mac / tkMacFont.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-15  |  18.1 KB  |  670 lines  |  [TEXT/CWIE]

  1. /* 
  2.  * tkMacFont.c --
  3.  *
  4.  *    Contains the Macintosh implementation of the platform-independant
  5.  *    font package interface.
  6.  *
  7.  * Copyright (c) 1990-1994 The Regents of the University of California.
  8.  * Copyright (c) 1994-1997 Sun Microsystems, Inc.
  9.  *
  10.  * See the file "license.terms" for information on usage and redistribution
  11.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  12.  *
  13.  * SCCS: @(#) tkMacFont.c 1.49 97/05/14 18:47:46
  14.  */
  15.  
  16. #include <Windows.h>
  17. #include <Strings.h>
  18. #include <Fonts.h>
  19. #include <Resources.h>
  20.  
  21. #include "tkMacInt.h"
  22. #include "tkFont.h"
  23. #include "tkPort.h"
  24.  
  25. /*
  26.  * The following structure represents the Macintosh's' implementation of a
  27.  * font.
  28.  */
  29.  
  30. typedef struct MacFont {
  31.     TkFont font;        /* Stuff used by generic font package.  Must
  32.                  * be first in structure. */
  33.     short family;
  34.     short size;
  35.     short style;
  36. } MacFont;
  37.  
  38. static GWorldPtr gWorld = NULL;
  39.  
  40. static TkFont *        AllocMacFont _ANSI_ARGS_((TkFont *tkfont, 
  41.                 Tk_Window tkwin, int family, int size, int style));
  42.  
  43.  
  44. /*
  45.  *---------------------------------------------------------------------------
  46.  *
  47.  * TkpGetNativeFont --
  48.  *
  49.  *    Map a platform-specific native font name to a TkFont.
  50.  *
  51.  * Results:
  52.  *     The return value is a pointer to a TkFont that represents the
  53.  *    native font.  If a native font by the given name could not be
  54.  *    found, the return value is NULL.  
  55.  *
  56.  *    Every call to this procedure returns a new TkFont structure,
  57.  *    even if the name has already been seen before.  The caller should
  58.  *    call TkpDeleteFont() when the font is no longer needed.
  59.  *
  60.  *    The caller is responsible for initializing the memory associated
  61.  *    with the generic TkFont when this function returns and releasing
  62.  *    the contents of the generics TkFont before calling TkpDeleteFont().
  63.  *
  64.  * Side effects:
  65.  *    None.
  66.  *
  67.  *---------------------------------------------------------------------------
  68.  */
  69.  
  70. TkFont *
  71. TkpGetNativeFont(
  72.     Tk_Window tkwin,    /* For display where font will be used. */
  73.     CONST char *name)    /* Platform-specific font name. */
  74. {
  75.     short family;
  76.     
  77.     if (strcmp(name, "system") == 0) {
  78.     family = GetSysFont();
  79.     } else if (strcmp(name, "application") == 0) {
  80.     family = GetAppFont();
  81.     } else {
  82.     return NULL;
  83.     }
  84.  
  85.     return AllocMacFont(NULL, tkwin, family, 0, 0);
  86. }
  87.  
  88. /*
  89.  *---------------------------------------------------------------------------
  90.  *
  91.  * TkpGetFontFromAttributes -- 
  92.  *
  93.  *    Given a desired set of attributes for a font, find a font with
  94.  *    the closest matching attributes.
  95.  *
  96.  * Results:
  97.  *     The return value is a pointer to a TkFont that represents the
  98.  *    font with the desired attributes.  If a font with the desired
  99.  *    attributes could not be constructed, some other font will be
  100.  *    substituted automatically.
  101.  *
  102.  *    Every call to this procedure returns a new TkFont structure,
  103.  *    even if the specified attributes have already been seen before.
  104.  *    The caller should call TkpDeleteFont() to free the platform-
  105.  *    specific data when the font is no longer needed.  
  106.  *
  107.  *    The caller is responsible for initializing the memory associated
  108.  *    with the generic TkFont when this function returns and releasing
  109.  *    the contents of the generic TkFont before calling TkpDeleteFont().
  110.  *
  111.  * Side effects:
  112.  *    None.
  113.  *
  114.  *---------------------------------------------------------------------------
  115.  */
  116. TkFont *
  117. TkpGetFontFromAttributes(
  118.     TkFont *tkFontPtr,        /* If non-NULL, store the information in
  119.                  * this existing TkFont structure, rather than
  120.                  * allocating a new structure to hold the
  121.                  * font; the existing contents of the font
  122.                  * will be released.  If NULL, a new TkFont
  123.                  * structure is allocated. */
  124.     Tk_Window tkwin,        /* For display where font will be used. */
  125.     CONST TkFontAttributes *faPtr)  /* Set of attributes to match. */
  126. {
  127.     char buf[257];
  128.     size_t len;
  129.     short family, size, style;
  130.  
  131.     if (faPtr->family == NULL) {
  132.     family = 0;
  133.     } else {
  134.     CONST char *familyName;
  135.  
  136.     familyName = faPtr->family;
  137.     if (strcasecmp(familyName, "Times New Roman") == 0) {
  138.         familyName = "Times";
  139.     } else if (strcasecmp(familyName, "Courier New") == 0) {
  140.         familyName = "Courier";
  141.     } else if (strcasecmp(familyName, "Arial") == 0) {
  142.         familyName = "Helvetica";
  143.     }
  144.         
  145.     len = strlen(familyName);
  146.     if (len > 255) {
  147.         len = 255;
  148.     }
  149.     buf[0] = (char) len;
  150.     memcpy(buf + 1, familyName, len);
  151.     buf[len + 1] = '\0';
  152.     GetFNum((StringPtr) buf, &family);
  153.     }
  154.  
  155.     size = faPtr->pointsize;
  156.     if (size <= 0) {
  157.     size = GetDefFontSize();
  158.     }
  159.  
  160.     style = 0;
  161.     if (faPtr->weight != TK_FW_NORMAL) {
  162.     style |= bold;
  163.     }
  164.     if (faPtr->slant != TK_FS_ROMAN) {
  165.     style |= italic;
  166.     }
  167.     if (faPtr->underline) {
  168.     style |= underline;
  169.     }
  170.  
  171.     return AllocMacFont(tkFontPtr, tkwin, family, size, style);
  172. }
  173.  
  174. /*
  175.  *---------------------------------------------------------------------------
  176.  *
  177.  * TkpDeleteFont --
  178.  *
  179.  *    Called to release a font allocated by TkpGetNativeFont() or
  180.  *    TkpGetFontFromAttributes().  The caller should have already
  181.  *    released the fields of the TkFont that are used exclusively by
  182.  *    the generic TkFont code.
  183.  *
  184.  * Results:
  185.  *    None.
  186.  *
  187.  * Side effects:
  188.  *    TkFont is deallocated.
  189.  *
  190.  *---------------------------------------------------------------------------
  191.  */
  192.  
  193. void
  194. TkpDeleteFont(
  195.     TkFont *tkFontPtr)        /* Token of font to be deleted. */
  196. {
  197.     ckfree((char *) tkFontPtr);
  198. }
  199.  
  200. /*
  201.  *---------------------------------------------------------------------------
  202.  *
  203.  * TkpGetFontFamilies --
  204.  *
  205.  *    Return information about the font families that are available
  206.  *    on the display of the given window.
  207.  *
  208.  * Results:
  209.  *    interp->result is modified to hold a list of all the available
  210.  *    font families.
  211.  *
  212.  * Side effects:
  213.  *    None.
  214.  *
  215.  *---------------------------------------------------------------------------
  216.  */
  217.  
  218. void
  219. TkpGetFontFamilies(
  220.     Tcl_Interp *interp,        /* Interp to hold result. */
  221.     Tk_Window tkwin)        /* For display to query. */
  222. {    
  223.     MenuHandle fontMenu;
  224.     int i;
  225.     char itemText[257];
  226.     
  227.     fontMenu = NewMenu(1, "\px");
  228.     AddResMenu(fontMenu, 'FONT');
  229.     
  230.     for (i = 1; i < CountMItems(fontMenu); i++) {
  231.         /*
  232.          * Each item is a pascal string. Convert it to C and append.
  233.          */
  234.         GetMenuItemText(fontMenu, i, (unsigned char *) itemText);
  235.         itemText[itemText[0] + 1] = '\0';
  236.         Tcl_AppendElement(interp, &itemText[1]);
  237.     }
  238.     DisposeMenu(fontMenu);
  239. }
  240.  
  241.  
  242. /*
  243.  *---------------------------------------------------------------------------
  244.  *
  245.  * TkMacIsCharacterMissing --
  246.  *
  247.  *    Given a tkFont and a character determines whether the character has
  248.  *    a glyph defined in the font or not. Note that this is potentially
  249.  *    not compatible with Mac OS 8 as it looks at the font handle
  250.  *    structure directly. Looks into the character array of the font
  251.  *    handle to determine whether the glyph is defined or not.
  252.  *
  253.  * Results:
  254.  *    Returns a 1 if the character is missing, a 0 if it is not.
  255.  *
  256.  * Side effects:
  257.  *    None.
  258.  *
  259.  *---------------------------------------------------------------------------
  260.  */
  261.  
  262. int
  263. TkMacIsCharacterMissing(
  264.     Tk_Font tkfont,        /* The font we are looking in. */
  265.     unsigned int searchChar)    /* The character we are looking for. */
  266. {
  267.     MacFont *fontPtr = (MacFont *) tkfont;
  268.     FMInput fm;
  269.     FontRec **fontRecHandle;
  270.     
  271.     fm.family = fontPtr->family;
  272.     fm.size = fontPtr->size;
  273.     fm.face = fontPtr->style;
  274.     fm.needBits = 0;
  275.     fm.device = 0;
  276.     fm.numer.h = fm.numer.v = fm.denom.h = fm.denom.v = 1;
  277.     
  278.     fontRecHandle = (FontRec **) FMSwapFont(&fm)->fontResult;
  279.     return *(short *) ((long) &(*fontRecHandle)->owTLoc 
  280.             + ((long)((*fontRecHandle)->owTLoc + searchChar 
  281.             - (*fontRecHandle)->firstChar) * sizeof(short))) == -1;
  282. }
  283.  
  284.  
  285. /*
  286.  *---------------------------------------------------------------------------
  287.  *
  288.  *  Tk_MeasureChars --
  289.  *
  290.  *    Determine the number of characters from the string that will fit
  291.  *    in the given horizontal span.  The measurement is done under the
  292.  *    assumption that Tk_DrawChars() will be used to actually display
  293.  *    the characters.
  294.  *
  295.  * Results:
  296.  *    The return value is the number of characters from source that
  297.  *    fit into the span that extends from 0 to maxLength.  *lengthPtr is
  298.  *    filled with the x-coordinate of the right edge of the last
  299.  *    character that did fit.
  300.  *
  301.  * Side effects:
  302.  *    None.
  303.  *
  304.  *---------------------------------------------------------------------------
  305.  */
  306.  
  307. int
  308. Tk_MeasureChars(
  309.     Tk_Font tkfont,        /* Font in which characters will be drawn. */
  310.     CONST char *source,        /* Characters to be displayed.  Need not be
  311.                  * '\0' terminated. */
  312.     int numChars,        /* Maximum number of characters to consider
  313.                  * from source string. */
  314.     int maxLength,        /* If > 0, maxLength specifies the longest
  315.                  * permissible line length; don't consider any
  316.                  * character that would cross this
  317.                  * x-position.  If <= 0, then line length is
  318.                  * unbounded and the flags argument is
  319.                  * ignored. */
  320.     int flags,            /* Various flag bits OR-ed together:
  321.                  * TK_PARTIAL_OK means include the last char
  322.                  * which only partially fit on this line.
  323.                  * TK_WHOLE_WORDS means stop on a word
  324.                  * boundary, if possible.
  325.                  * TK_AT_LEAST_ONE means return at least one
  326.                  * character even if no characters fit. */
  327.     int *lengthPtr)        /* Filled with x-location just after the
  328.                  * terminating character. */
  329. {
  330.     short staticWidths[128];
  331.     short *widths;
  332.     CONST char *p, *term;
  333.     int curX, termX, curIdx, sawNonSpace;
  334.     MacFont *fontPtr;
  335.     CGrafPtr saveWorld;
  336.     GDHandle saveDevice;
  337.  
  338.     if (numChars == 0) {
  339.     *lengthPtr = 0;
  340.     return 0;
  341.     }
  342.  
  343.     if (gWorld == NULL) {
  344.     Rect rect = {0, 0, 1, 1};
  345.  
  346.     if (NewGWorld(&gWorld, 0, &rect, NULL, NULL, 0) != noErr) {
  347.         panic("NewGWorld failed in Tk_MeasureChars");
  348.     }
  349.     }
  350.     GetGWorld(&saveWorld, &saveDevice);
  351.     SetGWorld(gWorld, NULL);
  352.  
  353.     fontPtr = (MacFont *) tkfont;
  354.     TextFont(fontPtr->family);
  355.     TextSize(fontPtr->size);
  356.     TextFace(fontPtr->style);
  357.  
  358.     if (maxLength <= 0) {
  359.         *lengthPtr = TextWidth(source, 0, numChars);
  360.         SetGWorld(saveWorld, saveDevice);
  361.         return numChars;
  362.     }
  363.  
  364.     if (numChars > maxLength) {
  365.         /*
  366.      * Assume that all chars are at least 1 pixel wide, so there's no
  367.      * need to measure more characters than there are pixels.  This
  368.      * assumption could be refined to an iterative approach that would
  369.      * use that as a starting point and try more chars if necessary (if
  370.      * there actually were some zero-width chars).
  371.      */
  372.  
  373.     numChars = maxLength;
  374.     }
  375.     if (numChars > SHRT_MAX) {
  376.     /*
  377.      * If they are trying to measure more than 32767 chars at one time,
  378.      * it would require several separate measurements.
  379.      */
  380.  
  381.     numChars = SHRT_MAX;
  382.     }
  383.  
  384.     widths = staticWidths;
  385.     if (numChars >= sizeof(staticWidths) / sizeof(staticWidths[0])) {
  386.     widths = (short *) ckalloc((numChars + 1) * sizeof(short));
  387.     }
  388.     
  389.     MeasureText((short) numChars, source, widths);
  390.     
  391.     if (widths[numChars] <= maxLength) {
  392.         curX = widths[numChars];
  393.         curIdx = numChars;
  394.     } else {
  395.         p = term = source;
  396.         curX = termX = 0;
  397.  
  398.     sawNonSpace = !isspace(UCHAR(*p));
  399.         for (curIdx = 1; ; curIdx++) {
  400.             if (isspace(UCHAR(*p))) {
  401.         if (sawNonSpace) {
  402.             term = p;
  403.             termX = widths[curIdx - 1];
  404.             sawNonSpace = 0;
  405.         }
  406.             } else {
  407.         sawNonSpace = 1;
  408.         }
  409.             if (widths[curIdx] > maxLength) {
  410.                 curIdx--;
  411.                 curX = widths[curIdx];
  412.                 break;
  413.             }
  414.             p++;
  415.         }
  416.         if (flags & TK_PARTIAL_OK) {
  417.             curIdx++;
  418.             curX = widths[curIdx];
  419.         }
  420.         if ((curIdx == 0) && (flags & TK_AT_LEAST_ONE)) {
  421.         /*
  422.          * The space was too small to hold even one character.  Since at
  423.          * least one character must always fit on a line, return the width
  424.          * of the first character.
  425.          */
  426.  
  427.         curX = TextWidth(source, 0, 1);
  428.         curIdx = 1;
  429.         } else if (flags & TK_WHOLE_WORDS) {
  430.         /*
  431.          * Break at last word that fits on the line.
  432.          */
  433.          
  434.         if ((flags & TK_AT_LEAST_ONE) && (term == source)) {
  435.         /*
  436.          * The space was too small to hold an entire word.  This
  437.          * is the only word on the line, so just return the part of th
  438.          * word that fit.
  439.          */
  440.          
  441.          ;
  442.             } else {
  443.         curIdx = term - source;
  444.         curX = termX;
  445.         }
  446.     }
  447.     }
  448.  
  449.     if (widths != staticWidths) {
  450.     ckfree((char *) widths);
  451.     }
  452.  
  453.     *lengthPtr = curX;
  454.     
  455.     SetGWorld(saveWorld, saveDevice);
  456.     
  457.     return curIdx;
  458. }
  459.  
  460. /*
  461.  *---------------------------------------------------------------------------
  462.  *
  463.  * Tk_DrawChars --
  464.  *
  465.  *    Draw a string of characters on the screen.  
  466.  *
  467.  * Results:
  468.  *    None.
  469.  *
  470.  * Side effects:
  471.  *    Information gets drawn on the screen.
  472.  *
  473.  *---------------------------------------------------------------------------
  474.  */
  475.  
  476. void
  477. Tk_DrawChars(
  478.     Display *display,        /* Display on which to draw. */
  479.     Drawable drawable,        /* Window or pixmap in which to draw. */
  480.     GC gc,            /* Graphics context for drawing characters. */
  481.     Tk_Font tkfont,        /* Font in which characters will be drawn;
  482.                  * must be the same as font used in GC. */
  483.     CONST char *source,        /* Characters to be displayed.  Need not be
  484.                  * '\0' terminated.  All Tk meta-characters
  485.                  * (tabs, control characters, and newlines)
  486.                  * should be stripped out of the string that
  487.                  * is passed to this function.  If they are
  488.                  * not stripped out, they will be displayed as
  489.                  * regular printing characters. */
  490.     int numChars,        /* Number of characters in string. */
  491.     int x, int y)        /* Coordinates at which to place origin of
  492.                  * string when drawing. */
  493. {
  494.     MacFont *fontPtr;
  495.     MacDrawable *macWin;
  496.     RGBColor macColor, origColor;
  497.     GWorldPtr destPort;
  498.     CGrafPtr saveWorld;
  499.     GDHandle saveDevice;
  500.     short txFont, txFace, txSize;
  501.     BitMapPtr stippleMap;
  502.  
  503.     fontPtr = (MacFont *) tkfont;
  504.     macWin = (MacDrawable *) drawable;
  505.  
  506.     destPort = TkMacGetDrawablePort(drawable);
  507.     GetGWorld(&saveWorld, &saveDevice);
  508.     SetGWorld(destPort, NULL);
  509.     
  510.     TkMacSetUpClippingRgn(drawable);
  511.     TkMacSetUpGraphicsPort(gc);
  512.     
  513.     txFont = tcl_macQdPtr->thePort->txFont;
  514.     txFace = tcl_macQdPtr->thePort->txFace;
  515.     txSize = tcl_macQdPtr->thePort->txSize;
  516.     GetForeColor(&origColor);
  517.     
  518.     if ((gc->fill_style == FillStippled
  519.         || gc->fill_style == FillOpaqueStippled)
  520.         && gc->stipple != None) {
  521.     Pixmap pixmap;
  522.     GWorldPtr bufferPort;
  523.     
  524.     stippleMap = TkMacMakeStippleMap(drawable, gc->stipple);
  525.  
  526.     pixmap = Tk_GetPixmap(display, drawable,     
  527.         stippleMap->bounds.right, stippleMap->bounds.bottom, 0);
  528.         
  529.     bufferPort = TkMacGetDrawablePort(pixmap);
  530.     SetGWorld(bufferPort, NULL);
  531.     
  532.     TextFont(fontPtr->family);
  533.     TextSize(fontPtr->size);
  534.     TextFace(fontPtr->style);
  535.     
  536.     if (TkSetMacColor(gc->foreground, &macColor) == true) {
  537.         RGBForeColor(&macColor);
  538.     }
  539.  
  540.     ShowPen();
  541.     MoveTo((short) 0, (short) 0);
  542.     FillRect(&stippleMap->bounds, &qd.white);
  543.     MoveTo((short) x, (short) y);
  544.     DrawText(source, 0, (short) numChars);
  545.  
  546.     SetGWorld(destPort, NULL);
  547.     CopyDeepMask(&((GrafPtr) bufferPort)->portBits, stippleMap, 
  548.         &((GrafPtr) destPort)->portBits, &stippleMap->bounds,
  549.         &stippleMap->bounds, &((GrafPtr) destPort)->portRect,
  550.         srcOr, NULL);
  551.     
  552.     /* TODO: this doesn't work quite right - it does a blend.   you can't
  553.      * draw white text when you have a stipple.
  554.      */
  555.         
  556.     Tk_FreePixmap(display, pixmap);
  557.     ckfree(stippleMap->baseAddr);
  558.     ckfree((char *)stippleMap);
  559.     } else {
  560.     TextFont(fontPtr->family);
  561.     TextSize(fontPtr->size);
  562.     TextFace(fontPtr->style);
  563.     
  564.     if (TkSetMacColor(gc->foreground, &macColor) == true) {
  565.         RGBForeColor(&macColor);
  566.     }
  567.  
  568.     ShowPen();
  569.     MoveTo((short) (macWin->xOff + x), (short) (macWin->yOff + y));
  570.     DrawText(source, 0, (short) numChars);
  571.     }
  572.  
  573.     TextFont(txFont);
  574.     TextSize(txSize);
  575.     TextFace(txFace);
  576.     RGBForeColor(&origColor);
  577.     SetGWorld(saveWorld, saveDevice);
  578. }
  579.  
  580. /*
  581.  *---------------------------------------------------------------------------
  582.  *
  583.  * AllocMacFont --
  584.  *
  585.  *    Helper for TkpGetNativeFont() and TkpGetFontFromAttributes().
  586.  *    Allocates and intializes the memory for a new TkFont that
  587.  *    wraps the platform-specific data.
  588.  *
  589.  * Results:
  590.  *    Returns pointer to newly constructed TkFont.  
  591.  *
  592.  *    The caller is responsible for initializing the fields of the
  593.  *    TkFont that are used exclusively by the generic TkFont code, and
  594.  *    for releasing those fields before calling TkpDeleteFont().
  595.  *
  596.  * Side effects:
  597.  *    Memory allocated.
  598.  *
  599.  *---------------------------------------------------------------------------
  600.  */ 
  601.  
  602. static TkFont *
  603. AllocMacFont(
  604.     TkFont *tkFontPtr,        /* If non-NULL, store the information in
  605.                  * this existing TkFont structure, rather than
  606.                  * allocating a new structure to hold the
  607.                  * font; the existing contents of the font
  608.                  * will be released.  If NULL, a new TkFont
  609.                  * structure is allocated. */
  610.     Tk_Window tkwin,        /* For display where font will be used. */
  611.     int family,            /* Macintosh font family. */
  612.     int size,            /* Point size for Macintosh font. */
  613.     int style)            /* Macintosh style bits. */
  614. {
  615.     char buf[257];
  616.     FontInfo fi;
  617.     MacFont *fontPtr;
  618.     TkFontAttributes *faPtr;
  619.     TkFontMetrics *fmPtr;
  620.     CGrafPtr saveWorld;
  621.     GDHandle saveDevice;
  622.  
  623.     if (gWorld == NULL) {
  624.     Rect rect = {0, 0, 1, 1};
  625.  
  626.     if (NewGWorld(&gWorld, 0, &rect, NULL, NULL, 0) != noErr) {
  627.         panic("NewGWorld failed in AllocMacFont");
  628.     }
  629.     }
  630.     GetGWorld(&saveWorld, &saveDevice);
  631.     SetGWorld(gWorld, NULL);
  632.  
  633.     if (tkFontPtr == NULL) {
  634.     fontPtr = (MacFont *) ckalloc(sizeof(MacFont));
  635.     } else {
  636.     fontPtr = (MacFont *) tkFontPtr;
  637.     }
  638.  
  639.     fontPtr->font.fid    = (Font) fontPtr;
  640.  
  641.     faPtr = &fontPtr->font.fa;
  642.     GetFontName(family, (StringPtr) buf);
  643.     buf[UCHAR(buf[0]) + 1] = '\0';
  644.     faPtr->family    = Tk_GetUid(buf + 1);
  645.     faPtr->pointsize    = size;
  646.     faPtr->weight    = (style & bold) ? TK_FW_BOLD : TK_FW_NORMAL;
  647.     faPtr->slant    = (style & italic) ? TK_FS_ITALIC : TK_FS_ROMAN;
  648.     faPtr->underline    = ((style & underline) != 0);
  649.     faPtr->overstrike    = 0;
  650.  
  651.     fmPtr = &fontPtr->font.fm;
  652.     TextFont(family);
  653.     TextSize(size);
  654.     TextFace(style);
  655.     GetFontInfo(&fi);
  656.     fmPtr->ascent    = fi.ascent;    
  657.     fmPtr->descent    = fi.descent;    
  658.     fmPtr->maxWidth    = fi.widMax;
  659.     fmPtr->fixed    = (CharWidth('i') == CharWidth('w'));
  660.  
  661.     fontPtr->family    = (short) family;
  662.     fontPtr->size    = (short) size;
  663.     fontPtr->style    = (short) style;
  664.  
  665.     SetGWorld(saveWorld, saveDevice);
  666.  
  667.     return (TkFont *) fontPtr;
  668. }
  669.  
  670.